#ifndef  HELPER_OBJECT_OBJECT_H
#define  HELPER_OBJECT_OBJECT_H

#include <string>

namespace helper {
namespace object {

/**
 * Common Object interface for all data objects
 * 
 * @author Cheng Lun
 * @email yunccll@sina.com
 * @since 0.1
 */
class Object {
public:
    /**
     *  Base Elements
     */
    enum Type{
        OBJECT = 0,
        INTEGER,
        DOUBLE,
        STRING,
        ARRAY,
        BYTE,
        HASH,
        POINTER,
    };

    /**
     * @param type   the type of the Object created
     */
    Object(Object::Type type) : type_(type) {}
    virtual ~Object() {}

    /**
     * @return true if the type of object is Array or false
     */
    bool isArray() const { return type_ == ARRAY;}
    /**
     * @return true if the type of object is Hash or false
     */
    bool isHash() const {return type_ == HASH;}
    /**
     * @return true if the type of object is String or false
     */
    bool isString() const {return type_ == STRING;}
    /**
     * @return true if the type of object is Byte or false
     */
    bool isByte() const {return type_ == BYTE;}
    /**
     * @return true if the type of object is INTEGER (64bit) or false
     */
    bool isInteger() const {return type_ == INTEGER;}
    /**
     * @return true if the type of object is Double (64bit) or false
     */
    bool isDouble() const {return type_ == DOUBLE;}

    bool isPointer() const {return type_ == POINTER;}

    /**
     * @return the real type of the object
     */
    Type getType() const {return type_;}

    /**
     * the string format of the object
     */
    virtual std::string toString() const = 0;

    bool operator == (const Object & right) const {
        return equals(right);
    }
    bool operator != (const Object & right) const {
        return !(*this == right);
    }

    virtual bool equals(const Object & right) const = 0;

    template<typename T>
    T *  clone() const {
        Object * newObj = copy();
        return getType() == newObj->getType() ? static_cast<T *>(newObj) : nullptr;
    }

    virtual Object * copy() const = 0;
private:
    Type type_;
    //TODO:ObjectFactory * factory;
};


} // end of namespace object
} // end of namespace helper

#endif   /* HELPER_OBJECT_OBJECT_H */
